package org.example.comp_algorithm_back.algorithm;

import com.hankcs.hanlp.HanLP;
import org.example.comp_algorithm_back.domain.Result;
import org.example.comp_algorithm_back.domain.CompWord;

import org.example.comp_algorithm_back.util.PathClass;
import org.example.comp_algorithm_back.vo.KeywordVo;


import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static com.baomidou.mybatisplus.extension.toolkit.Db.save;

public class CompKey {

    public static void compkey(String wordKey, int n, KeywordVo vo,int choice) throws UnsupportedEncodingException, IOException, Exception {
        System.out.println("开始从总搜索量中提取出与种子关键词相关的搜索信息...");

        boolean setPinyin=false;
        InputStreamReader inStream0 = new InputStreamReader(new FileInputStream(PathClass.wordOut), StandardCharsets.UTF_8);//读取总搜索量文件
        OutputStreamWriter outStream0 = new OutputStreamWriter(new FileOutputStream(PathClass.wordRelated), StandardCharsets.UTF_8);
        BufferedReader bf0 = new BufferedReader(inStream0);
        BufferedWriter bw0 = new BufferedWriter(outStream0);
        String valueString0 = null;
        while ((valueString0=bf0.readLine())!=null){  //与种子关键字相关的搜索信息
            if(valueString0.contains(wordKey)) {
                bw0.append(valueString0);
                bw0.newLine();
            }
        }
        bw0.close();
        File f = new File(PathClass.wordRelated);
        if(f.length() < 50) {
            System.out.println("搜索日志中关键词的同音词");
            inStream0 = new InputStreamReader(new FileInputStream(PathClass.wordOut), StandardCharsets.UTF_8);//读取总搜索量文件
            outStream0 = new OutputStreamWriter(new FileOutputStream(PathClass.wordRelated), StandardCharsets.UTF_8);
            bf0 = new BufferedReader(inStream0);
            bw0 = new BufferedWriter(outStream0);
            String pinyin = HanLP.convertToPinyinString(wordKey, "", true);
            while ((valueString0=bf0.readLine())!=null){  //与种子关键字相关的搜索信息
                String target = HanLP.convertToPinyinString(valueString0, "", true);
                if(target.contains(pinyin)) {
                    bw0.append(valueString0);
                    bw0.newLine();
                }
            }
            bw0.close();
            setPinyin=true;
        }
        if(f.length() == 0) {
            System.out.println("搜索日志中不含关键词“" + wordKey +"”，请重新设置种子关键词！！！");
            vo.setWordMsg("搜索日志中不含关键词“" + wordKey +"”，请重新设置种子关键词！！！");
            return;
        }
        System.out.println("相关信息长度："+f.length());
        System.out.println("开始对与种子关键字相关的搜索信息进行分词与词频统计...");

        switch (choice){
            case 1:
                System.out.println("分词库选择apdplat");
                MainDataClass.statistic(PathClass.wordRelated, PathClass.wordApart, PathClass.wordStatistics);
                break;
            case 2:
                System.out.println("分词库选择HanLP");
                HanlpWord.statistic(PathClass.wordRelated, PathClass.wordApart, PathClass.wordStatistics);
                break;
            default:
                System.out.println("分词库选择ansj");
                AnsjWord.statistic(PathClass.wordRelated, PathClass.wordApart, PathClass.wordStatistics);
                break;
        }
          //从原数据中提取出与种子关键词相关的搜索信息

        System.out.println("开始查找中介关键词...");
        /*用关键词的频率来代替权重，找出前n个中介关键词，并将保存到文件wordMidKey中*/
        InputStreamReader inStream = new InputStreamReader(new FileInputStream(PathClass.wordStatistics), StandardCharsets.UTF_8);
        BufferedReader bf = new BufferedReader(inStream);
        PrintStream ps = new PrintStream(PathClass.wordMidKey);/*保存屏幕信息*/
        PrintStream out = System.out;
        System.setOut(ps);
        String valueString = null;
        int sum = 0;
        valueString = bf.readLine();
        while ((valueString = bf.readLine()) != null) {
            int temp = valueString.indexOf(" ");
            valueString = valueString.substring(0, temp);
            if (valueString.contains(wordKey)) { //过滤掉包含关键字的中介关键词
                continue;
            } else {
                System.out.println(valueString);
                sum++;
            }
            if (sum == n) {
                break;
            }
        }
        n = sum;
        vo.setWordCount(n);
        System.setOut(out);
        System.out.println("开始查找竞争性关键词，并计算竞争度...");
        /*寻找竞争性关键词*/
        InputStreamReader inStreamR = new InputStreamReader(new FileInputStream(PathClass.wordMidKey), StandardCharsets.UTF_8);//读取文件
        BufferedReader bfr = new BufferedReader(inStreamR);
        WordKey[] wordK = new WordKey[n];
        for (int i = 0; i < n; i++) {
            wordK[i] = new WordKey();
        }

        for (int i = 0; i < n; i++) {
            String wordMidKey = bfr.readLine();   //中介关键词
            InputStreamReader inStream1 = new InputStreamReader(new FileInputStream(PathClass.wordOut), StandardCharsets.UTF_8);//读取文件
            OutputStreamWriter outStream = new OutputStreamWriter(new FileOutputStream(PathClass.wordTempKey), StandardCharsets.UTF_8);
            BufferedReader bf1 = new BufferedReader(inStream1);
            BufferedWriter bw1 = new BufferedWriter(outStream);
            String valueString1 = null;
            AtomicInteger a = new AtomicInteger(); //所有含中介关键词的搜索量
            // 创建线程池
            ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            while ((valueString1 = bf1.readLine()) != null) {  //与种子关键字相关的搜索信息
                String finalValueString = valueString1;
                if(!setPinyin)
                {
                    executor.submit(() -> {
                        if (finalValueString.contains(wordMidKey)&&!finalValueString.contains(wordKey)) {
                            try {
                                bw1.write(finalValueString);
                                bw1.newLine();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            a.getAndIncrement();
                        }
                    });
                }
                else {
                    executor.submit(() -> {
                        String pinyin = HanLP.convertToPinyinString(wordKey, "", true);
                        String target = HanLP.convertToPinyinString(finalValueString, "", true);
                        if (finalValueString.contains(wordMidKey)&&!target.contains(pinyin)) {
                            try {
                                bw1.write(finalValueString);
                                bw1.newLine();
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                            a.getAndIncrement();
                        }
                    });
                }
            }
            // 关闭线程池
            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.MINUTES);
            bw1.close();

            switch (choice){
                case 1:
                    MainDataClass.statistic(PathClass.wordTempKey, PathClass.wordTempApart, PathClass.wordTempStatistics);
                    break;
                case 2:
                    HanlpWord.statistic(PathClass.wordTempKey, PathClass.wordTempApart, PathClass.wordTempStatistics);
                    break;
                default:
                    AnsjWord.statistic(PathClass.wordTempKey, PathClass.wordTempApart, PathClass.wordTempStatistics);//对相关信息进行分词和词频统计
                    break;
            }


            /*寻找竞争关键词*/
            InputStreamReader inStream2 = new InputStreamReader(new FileInputStream(PathClass.wordTempStatistics), StandardCharsets.UTF_8);//读取文件
            BufferedReader bf2 = new BufferedReader(inStream2);
            String wordCompKey = null;
            while((wordCompKey = bf2.readLine()) != null) {
                int temp = wordCompKey.indexOf(" ");
                wordCompKey = wordCompKey.substring(0, temp);
                char c = wordCompKey.charAt(0);
                if((c >= '0' && c <= '9')) continue;/*去掉数字*/
                if(!wordCompKey.contains(wordMidKey) && !wordCompKey.contains(wordKey)) {
                    break;
                }
            }

            /*统计同时包含竞争关键字和中介关键字的搜索量*/
            InputStreamReader inStream3 = new InputStreamReader(new FileInputStream(new File(PathClass.wordOut)), StandardCharsets.UTF_8);//读取文件
            BufferedReader bf3 = new BufferedReader(inStream3);
            String valueString3 = null;
            int ka = 0; //同时包含关键字和中介关键字的搜索量
            int sa = 0; //同时包含竞争关键字和中介关键字的搜索量
            if (!setPinyin) {
                while ((valueString3 = bf3.readLine()) != null) {
                    if (wordCompKey != null && valueString3.contains(wordMidKey) && valueString3.contains(wordKey) && !valueString3.contains(wordCompKey)) {
                        ka++;
                    }
                    if (wordCompKey != null && valueString3.contains(wordMidKey) && valueString3.contains(wordCompKey) && !valueString3.contains(wordKey)) {
                        sa++;
                    }
                }
            }
            else {
                String pinyin = HanLP.convertToPinyinString(wordKey, "", true);
                while ((valueString3 = bf3.readLine()) != null) {
                    String target = HanLP.convertToPinyinString(valueString3, "", true);
                    if (wordCompKey != null && valueString3.contains(wordMidKey) && target.contains(pinyin) && !valueString3.contains(wordCompKey)) {
                        ka++;
                    }
                    if (wordCompKey != null && valueString3.contains(wordMidKey) && valueString3.contains(wordCompKey) && !target.contains(pinyin)) {
                        sa++;
                    }
                }
            }
//            System.out.println(ka);
//            System.out.println(sa);
//            System.out.println(a.get());
            double ans;
            if(a.get() - sa == 0) {
                ans = -1;
            } else {
                ans = (double)ka / (double)(a.get() - sa);
            }

            DecimalFormat df = new DecimalFormat("#.#####");
            ans = Double.parseDouble(df.format(ans));
            wordK[i].wordKeyInit(wordKey, wordMidKey, wordCompKey, ans);
            System.out.println("已完成第" + (i + 1) + "条数据统计:" + "(种子)" + wordKey + "\t" + "(中介)" + wordMidKey + "\t" + "(竞争)" + wordCompKey + "\t竞争度：" + String.format("%.16f", ans));
        }
        /*竞争性关键词排序打印*/
        WordKey tempWord;
        for(int i = 0; i < n - 1; i++) {
            for(int j = 0; j < n - i - 1; j++) {
                if(wordK[j].compPower < wordK[j + 1].compPower) {
                    tempWord = wordK[j];
                    wordK[j] = wordK[j + 1];
                    wordK[j + 1] = tempWord;
                }
            }
        }
        String Result = PathClass.wordResult + wordKey + PathClass.txt;
        PrintStream ps1 = new PrintStream(Result);/*保存屏幕信息*/
        System.setOut(ps1);
        System.out.println("“" + wordKey + "”的竞争性关键词关于竞争度排序如下:");
        for(int i = 0; i < n; i++) {
            wordK[i].wordKeyPrint();
            CompWord compWord = new CompWord();
            compWord.setMidWord(wordK[i].wordMidKey);
            compWord.setWord(wordK[i].wordCompKey);
            compWord.setComp(wordK[i].compPower);
            vo.getKeywords().add(compWord);


//            Result result1=new Result();
//            result1.setCompKey(wordK[i].wordCompKey);
//            result1.setComp(wordK[i].compPower);
//            result1.setMidKey(wordK[i].wordMidKey);
//            result1.setSeedWord(wordKey);
//            save(result1);
        }
        System.setOut(out);
        System.out.println("CompKey算法结束...");
        System.out.println();
    }
}
